﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using BlueNinjaSoftware.HIDLib;
using BlueNinjaSoftware.HIDLib.Reports;
using System.Xml.Serialization;
using System.IO;
using WindowsInput;

namespace StrategicCommanderCenter
{
    /// <summary>
    /// Logica di interazione per MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private XmlSerializer serializer;
        private TextWriter writer;
        private TextReader reader;
        /*
using System.Runtime.InteropServices;
        [DllImport("user32.dll")]
        static extern short VkKeyScan(char ch);
        
        [DllImport("user32.dll")]
        internal static extern uint MapVirtualKey(uint uCode, uint uMapType);*/
        private StrategicConfig config;
        private EventShooter shooter;
        private HIDDevice dev;
        private ReportDecoder decoder;
        private StrategicState state;
        private LEDManager manager;
        private List<Key> currPressedKey;

        public MainWindow()
        {
            InitializeComponent();
            
            IList<HIDDevice> devs = HIDManagement.GetDevices(1118, 51); //Codes for Microsoft Strategic Commander

            serializer = new XmlSerializer(typeof(StrategicConfig));
            currPressedKey = new List<Key>();
            if (File.Exists("profile.xml"))
            {
            reader = new StreamReader("profile.xml");
            config = (StrategicConfig)serializer.Deserialize(reader);
            reader.Close();
            reader = null;
            }
            else
            {
                writer = new StreamWriter("profile.xml");
                serializer.Serialize(writer, new StrategicConfig());
                writer.Close();
                writer = null;
            }

            if ((devs == null) || (devs.Count == 0))
            {
                System.Windows.MessageBox.Show("No device found!");
            }
            else
            {
                dev = devs[0];
                decoder = new ReportDecoder(dev);
                shooter = new EventShooter(decoder, config, false);
                shooter.ButtonPress += this.ButtonPress;
                shooter.ButtonRelease += this.ButtonRelease;

                decoder.Changed += this.ChangedStateHandler;
                manager = new LEDManager(dev, decoder, config);
                decoder.Start();
            }

            state = new StrategicState();            
            //DeviceStatus.DataContext = state;
            ProfilesConfig.ItemsSource = config.Profiles;            
        }

        private void OnDataChange(object sender, RoutedEventArgs e)
        {
        }

        private void ButtonPress(object sender, ButtonArgs e)
        {
            int shift = (int)e.Shift;
            
            switch (e.Button)
            {
                case StrategicButtons.Button1:
                    break;
                case StrategicButtons.Button2:
                    break;
                case StrategicButtons.Button3:
                    break;
                case StrategicButtons.Button4:
                    break;
                case StrategicButtons.Button5:
                    break;
                case StrategicButtons.Button6:
                    break;
                case StrategicButtons.ZoomIn:
                    break;
                case StrategicButtons.ZoomOut:
                    break;
                case StrategicButtons.Shift1:
                    break;
                case StrategicButtons.Shift2:
                    break;
                case StrategicButtons.Shift3:
                    break;
                case StrategicButtons.Rec:
                    break;
                default:
                    break;
            }
        }

        private void ButtonRelease(object sender, ButtonArgs e)
        {
        }

        private void StrategicCommandCenter_Closed(object sender, EventArgs e)
        {
            if (decoder != null)
            decoder.Stop();
            if (manager != null)
            manager.Dispose();
        }

        private void ChangedStateHandler(object sender, ChangedStateArgs e)
        {
            state.CopyValuesFrom(e.NewState);
            this.Dispatcher.Invoke(new Action(delegate()
            {
                sliderX.Value = e.NewState.XAxis;
                sliderY.Value = e.NewState.YAxis;
                curvedSlider1.Slider.Value = e.NewState.Rotation;
                button1.IsChecked = e.NewState.ButtonStates[0];
                button2.IsChecked = e.NewState.ButtonStates[1];
                button3.IsChecked = e.NewState.ButtonStates[2];
                button4.IsChecked = e.NewState.ButtonStates[3];
                button5.IsChecked = e.NewState.ButtonStates[4];
                button6.IsChecked = e.NewState.ButtonStates[5];
                shift1.IsChecked = e.NewState.ButtonStates[(int)StrategicButtons.Shift1];
                shift2.IsChecked = e.NewState.ButtonStates[(int)StrategicButtons.Shift2];
                shift3.IsChecked = e.NewState.ButtonStates[(int)StrategicButtons.Shift3];

                zoomIn.IsChecked = e.NewState.ButtonStates[(int)StrategicButtons.ZoomIn];
                zoomOut.IsChecked = e.NewState.ButtonStates[(int)StrategicButtons.ZoomOut];

                rec.IsChecked = e.NewState.ButtonStates[(int)StrategicButtons.Rec];

                switch (e.NewState.CurrentProfile)
                {
                    case StrategicProfileSelector.Profile1: profile1.IsChecked = true;
                        break;
                    case StrategicProfileSelector.Profile2: profile2.IsChecked = true;
                        break;
                    case StrategicProfileSelector.Profile3: profile3.IsChecked = true;
                        break;
                }

            }));
            /*
            this.Dispatcher.Invoke(new Action(delegate()
            {
                BindingOperations.GetBindingExpressionBase(sliderX, Slider.ValueProperty).UpdateTarget();
                BindingOperations.GetBindingExpressionBase(sliderY, Slider.ValueProperty).UpdateTarget();
                BindingOperations.GetBindingExpressionBase(sliderZ, Slider.ValueProperty).UpdateTarget();
            }));*/
        }

        private void StrategicCommandCenter_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.Hide();
            if (shooter != null)
                shooter.FireProfileKeys = true;
        }

        private void StrategicCommandCenter_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (shooter != null)
                shooter.FireProfileKeys = !(bool)e.NewValue;
        }

        private void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.DefaultExt = ".xml";
            dlg.Filter = "XML Profile (.xml)|*.xml";
            if (dlg.ShowDialog() == true)
            {
                writer = new StreamWriter(dlg.FileName);
                serializer.Serialize(writer, config);
                writer.Flush();
                writer.Close();
            }
        }

        private void LoadButton_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = ".xml";
            dlg.Filter = "XML Profile (.xml)|*.xml";
            if (dlg.ShowDialog() == true)
            {
                reader = new StreamReader(dlg.FileName);
                config = (StrategicConfig)serializer.Deserialize(reader);
                //TODO: Refresh bindings?
                reader.Close();
                reader = null;
            }
        }

        private void ProfilesConfig_PreviewKeyUp(object sender, KeyEventArgs e)
        {
            //
            //MessageBox.Show(e.Key.ToString());
            IInputElement focus = FocusManager.GetFocusedElement(this);
            if (focus is TextBox)
            {
                e.Handled = true;                
            }
        }

        private void ProfilesConfig_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            /*
            IInputElement focus = FocusManager.GetFocusedElement(this);
            if (focus is TextBox)
            {
                e.Handled = true;
                String name = ((TextBox)focus).Name;
                String pname = ((Control)((TextBox)focus).Parent).Name;
            }
            */
        }

    }
}
